<?php

/**
 * 微信辅助组件
 * 
 * @author Lonxon
 * @version 1.5 Core
 */
class Core_Plugin_WeiXin {

    /**
     * c => 菱花购
     * b => 美好菱花
     */
    //     public static $wx_app = array(
    //         'c' => array(
    //             'appid' => 'wxd1f37c58d3c6dbc0',
    //             'appsecret' => '9ad5015270cfed65baf6e623f5298f11',
    //             'mchid' => '1249475801',
    //             'key' => '33060330623306933060330662330673',
    //             'sslcert_path' => '/statics/cert/cdj_c/apiclient_cert.pem',
    //             'sslkey_path' => '/statics/cert/cdj_c/apiclient_key.pem'
    //         ),
    //         'b' => array( // 美好菱花
    //             'appid' => 'wx5d06c36715e15e18',
    //             'appsecret' => '9cc7b1fa2eb1b7b576279a33ac9793d0',
    //             'mchid' => '',
    //             'key' => '',
    //             'sslcert_path' => '/statics/cert/cdj_b/apiclient_cert.pem',
    //             'sslkey_path' => '/statics/cert/cdj_b/apiclient_key.pem'
    //         )
    //     );
    
    /**
     * c => 菜到家_C
     * b => 菜到家_B，
     */
    public static $wx_app = array(
        'c' => array(
            'appid' => 'wx6a6acb96a0a4f505',
            'appsecret' => '24bd02ddfc814a377383e6e950f5f38c',
            'mchid' => '1240875702',
            'key' => '96385274123654789e69dq36k2m8l2x0',
            'sslcert_path' => '/statics/cert/cdj_c/apiclient_cert.pem',
            'sslkey_path' => '/statics/cert/cdj_c/apiclient_key.pem'
        ),
        'b' => array(
            'appid' => 'wxee9c0af06a042249',
            'appsecret' => '82c30c90a9f80e89ba770f2f0e4c90f1',
            'mchid' => '',
            'key' => '',
            'sslcert_path' => '/statics/cert/cdj_b/apiclient_cert.pem',
            'sslkey_path' => '/statics/cert/cdj_b/apiclient_key.pem'
        )
    );

    /**
     * 微信TOKEN键名前缀
     */
    const TOKEN_KEY = "CDJ_TOKEN_";

    /**
     * 微信JS签名键名前缀
     */
    const JSSIGN_KEY = "CDJ_JSSIGN_";

    /**
     * 消息模板发送
     * 
     * @param string $type <pre>类型有:
     *        wait_active => 下单成功等待接单 发给消费者
     *        remind_active => 接单提醒 发给店家
     *        get_new_order => 有新单通知 发给店家
     *        pay_ok => 支付成功 发给消费者
     *        no_ok => 取消通知 发给消费者
     *        reject_ok => 拒单通知 发给消费者
     *        active_ok => 接单通知 发给消费者
     *        complete_ok_tob => 完成通知 发给店家
     *        complete_ok_toc => 完成通知 发给消费者
     * @param string $touser 接收者的OPENID
     * @param string $url 推送消息点击后跳转的链接
     * @param array $data 模版参数集合
     * @return boolean
     */
    static public function sendTemp($type, $touser, $url, $data) {
        $type = $type && is_string($type) && in_array($type, array(
            'wait_active',
            'get_new_order',
            'remind_active',
            'pay_ok',
            'no_ok',
            'reject_ok',
            'active_ok',
            'complete_ok_tob',
            'complete_ok_toc'
        )) ? $type : false;
        $touser = Core_Plugin_Tool::checkStr($touser, 'op');
        if (($type != false) && ($touser != false)) {
            $params = array(
                'touser' => $touser,
                'url' => urlencode($url),
                'topcolor' => '#FF0000',
                'template_id' => '',
                'data' => array()
            );
            switch ($type) {
                case 'wait_active':
                    if ($data && isset($data['sn']) && isset($data['cost']) && $data['sn'] && (floatval($data['cost']) > 0)) {
                        $token = self::getToken('c');
                        // 订单提交成功通知
                        $params['template_id'] = 'p-4AohlDJsAg0gM_iIWu-n5GqknJNhQ6Fegr4fCMtek';
                        $params['data']['first'] = array(
                            'value' => urlencode('您的订单已提交，请耐心等待店家的接单提醒')
                        );
                        $params['data']['keyword1'] = array(
                            'value' => urlencode($data['sn'])
                        );
                        $params['data']['keyword2'] = array(
                            'value' => urlencode(date('Y-m-d H:i:s', time()))
                        );
                        $params['data']['keyword3'] = array(
                            'value' => urlencode(sprintf('%.2f 元', $data['cost']))
                        );
                        $params['data']['remark'] = array(
                            'value' => urlencode('温馨提示: 商家过忙或其他原因可能会拒绝接收订单')
                        );
                        Core_Plugin_Http::request("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={$token}", $params, 'JSON');
                        return true;
                    }
                    return false;
                    break;
                case 'remind_active':
                    if ($data && isset($data['sn']) && isset($data['cost']) && isset($data['body']) && isset($data['atime']) && $data['sn'] && (floatval($data['cost']) > 0) && $data['body'] && $data['atime']) {
                        $token = self::getToken('b');
                        // 订单确认提醒
                        $params['template_id'] = '7r4gnA2v4k7PM3KhMaYYo_gi182G0Qah-e_bv4uGydU';
                        $params['data']['first'] = array(
                            'value' => urlencode('提醒一下店家，我的订单已提交，请尽快接单，谢谢')
                        );
                        $params['data']['keyword1'] = array(
                            'value' => urlencode($data['sn'])
                        );
                        $params['data']['keyword2'] = array(
                            'value' => urlencode($data['atime'])
                        );
                        $params['data']['keyword3'] = array(
                            'value' => urlencode($data['body'])
                        );
                        $params['data']['keyword4'] = array(
                            'value' => urlencode(sprintf('%.2f 元', $data['cost']))
                        );
                        $params['data']['remark'] = array(
                            'value' => urlencode('点击查看详情哦~')
                        );
                        Core_Plugin_Http::request("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={$token}", $params, 'JSON');
                        return true;
                    }
                    return false;
                    break;
                case 'get_new_order':
                    if ($data && isset($data['sn']) && isset($data['cost']) && isset($data['body']) && isset($data['atime']) && $data['sn'] && (floatval($data['cost']) > 0) && $data['body'] && $data['atime']) {
                        $token = self::getToken('b');
                        // 新订单提醒
                        $params['template_id'] = '7r4gnA2v4k7PM3KhMaYYo_gi182G0Qah-e_bv4uGydU';
                        $params['data']['first'] = array(
                            'value' => urlencode('店家您好，您有新订单了,请及时确认')
                        );
                        $params['data']['keyword1'] = array(
                            'value' => urlencode($data['sn'])
                        );
                        $params['data']['keyword2'] = array(
                            'value' => urlencode($data['atime'])
                        );
                        $params['data']['keyword3'] = array(
                            'value' => urlencode($data['body'])
                        );
                        $params['data']['keyword4'] = array(
                            'value' => urlencode(sprintf('%.2f 元', $data['cost']))
                        );
                        $params['data']['remark'] = array(
                            'value' => urlencode('点击查看详情哦~')
                        );
                        Core_Plugin_Http::request("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={$token}", $params, 'JSON');
                        return true;
                    }
                    return false;
                    break;
                case 'pay_ok':
                    if ($data && isset($data['sn']) && isset($data['cost']) && $data['sn'] && (floatval($data['cost']) > 0)) {
                        $token = self::getToken('c');
                        // 订单支付成功通知
                        $params['template_id'] = 'n0BqAfOnwneGo2Qbaa0R9iM0uhuWST49dwpLNho8T4g';
                        $params['data']['first'] = array(
                            'value' => urlencode('您好，您的订单已提交并支付，请耐心等待店家的接单提醒 ')
                        );
                        $params['data']['keyword1'] = array(
                            'value' => urlencode($data['sn'])
                        );
                        $params['data']['keyword2'] = array(
                            'value' => urlencode(sprintf('%.2f 元', $data['cost']))
                        );
                        $params['data']['remark'] = array(
                            'value' => urlencode('温馨提示: 商家过忙或其他原因可能会拒绝接收订单')
                        );
                        Core_Plugin_Http::request("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={$token}", $params, 'JSON');
                        return true;
                    }
                    return false;
                    break;
                case 'no_ok':
                    if ($data && isset($data['sn']) && $data['sn']) {
                        $token = self::getToken('c');
                        // 订单取消通知
                        $params['template_id'] = 'pzH0_qhMNsZd_glolFllwMaPKagOkoqxwjKJhJPTODg';
                        $params['data']['first'] = array(
                            'value' => urlencode('您好，您的订单已取消')
                        );
                        $params['data']['keyword1'] = array(
                            'value' => urlencode($data['sn'])
                        );
                        $params['data']['keyword2'] = array(
                            'value' => urlencode(date('Y-m-d H:i', time()))
                        );
                        $params['data']['remark'] = array(
                            'value' => urlencode('点击查看详情哦~')
                        );
                        Core_Plugin_Http::request("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={$token}", $params, 'JSON');
                        return true;
                    }
                    return false;
                    break;
                case 'reject_ok':
                    if ($data && isset($data['sn']) && $data['sn']) {
                        $token = self::getToken('c');
                        // 拒绝订单通知
                        $params['template_id'] = 'pzH0_qhMNsZd_glolFllwMaPKagOkoqxwjKJhJPTODg';
                        $params['data']['first'] = array(
                            'value' => urlencode('您好，您的订单已被商家拒单')
                        );
                        $params['data']['keyword1'] = array(
                            'value' => urlencode($data['sn'])
                        );
                        $params['data']['keyword2'] = array(
                            'value' => urlencode(date('Y-m-d H:i', time()))
                        );
                        $params['data']['remark'] = array(
                            'value' => urlencode('商家过忙或其他原因；另外，若您已支付，支付的金额将在1到5个工作日退回。')
                        );
                        Core_Plugin_Http::request("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={$token}", $params, 'JSON');
                        return true;
                    }
                    return false;
                    break;
                case 'active_ok':
                    if ($data && isset($data['sname']) && isset($data['sn']) && isset($data['mobile']) && $data['sname'] && $data['sn'] && Core_Plugin_Tool::isMobile($data['mobile'])) {
                        $token = self::getToken('c');
                        // 商铺接单通知
                        $params['template_id'] = 'CD51wZsnBPtLWEJ3v7dNPdp5AdvYrQ0LWeyiGjtnKgc';
                        $params['data']['first'] = array(
                            'value' => urlencode('您好，您的订单已被商铺接单')
                        );
                        $params['data']['keyword1'] = array(
                            'value' => urlencode($data['sname'])
                        );
                        $params['data']['keyword2'] = array(
                            'value' => urlencode(date('Y-m-d H:i', time()))
                        );
                        $params['data']['keyword3'] = array(
                            'value' => urlencode($data['sn'])
                        );
                        $params['data']['remark'] = array(
                            'value' => urlencode("订单处理中，若有问题可联系店家【TEL： {$data['mobile']}】")
                        );
                        Core_Plugin_Http::request("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={$token}", $params, 'JSON');
                        return true;
                    }
                    return false;
                    break;
                case 'complete_ok_tob':
                    if ($data && isset($data['sn']) && isset($data['cost']) && $data['sn'] && (floatval($data['cost']) > 0)) {
                        $token = self::getToken('b');
                        // 订单完成通知 发给商家
                        $params['template_id'] = 'G2arpsq5o8NSlFXLUPNPvjZchsIrXcwDipVeswi2zxg';
                        $params['data']['first'] = array(
                            'value' => urlencode('店家您好，该单已被用户确认完成，再接再励哟~')
                        );
                        $params['data']['orderno'] = array(
                            'value' => urlencode($data['sn'])
                        );
                        $params['data']['amount'] = array(
                            'value' => urlencode(sprintf('%.2f 元', $data['cost']))
                        );
                        $params['data']['remark'] = array(
                            'value' => urlencode('点击查看详情哦~')
                        );
                        Core_Plugin_Http::request("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={$token}", $params, 'JSON');
                        return true;
                    }
                    return false;
                    break;
                case 'complete_ok_toc':
                    if ($data && isset($data['sn']) && isset($data['body']) && isset($data['mobile']) && $data['sn'] && $data['body'] && Core_Plugin_Tool::isMobile($data['mobile'])) {
                        $token = self::getToken('c');
                        // 订单完成通知 发给消费者
                        $params['template_id'] = 'mrOGbBi9hmqiDgi4DeKolHbpMTVVkE4MhP_94SwISVc';
                        $params['data']['first'] = array(
                            'value' => urlencode('您好，您的订单已完成')
                        );
                        $params['data']['keyword1'] = array(
                            'value' => urlencode($data['sn'])
                        );
                        $params['data']['keyword2'] = array(
                            'value' => urlencode($data['body'])
                        );
                        $params['data']['remark'] = array(
                            'value' => urlencode("订单已完成，若有问题可联系店家【TEL： {$data['mobile']}】")
                        );
                        Core_Plugin_Http::request("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={$token}", $params, 'JSON');
                        return true;
                    }
                    return false;
                    break;
                default:
                    return false;
            }
        }
        return false;
    }

    /**
     * 平台绑定验证
     */
    static public function valid() {
        if (isset($_GET['echostr'])) {
            $tmp = array(
                TOKEN,
                $_GET["timestamp"],
                $_GET["nonce"]
            );
            sort($tmp);
            $flag = sha1(implode($tmp)) == $_GET["signature"];
            if ($flag) {
                exit($_GET["echostr"]);
            }
        }
    }

    /**
     * 微信缓存数据检验
     * 
     * @param string $type 字符串类型 <pre>分类：
     *        jssign => 微信TOKEN
     *        jssign => 微信JS签名
     * @param string $m 模块名称 [b/c]
     * @return boolean|string
     */
    static public function getStr($type, $m) {
        $type = $type && is_string($type) && in_array($type, array(
            'token',
            'jssign'
        )) ? $type : false;
        if ($type == false) {
            return false;
        }
        $res = false;
        switch ($type) {
            case 'token':
                $res = Jf::cache()->get(self::TOKEN_KEY . $m);
                break;
            case 'jssign':
                $res = Jf::cache()->get(self::JSSIGN_KEY . $m);
                break;
            default:
                break;
        }
        $res = Core_Plugin_Tool::checkStr($res, 'wx') ? $res : false;
        if ($res) {
            $res = explode(':', $res);
            $res = $res && (time() - intval($res[0]) <= 7000) ? $res[1] : false;
        }
        return $res;
    }

    /**
     * 获取基础支持TOKEN
     * 
     * @param string $m 模块名称 [b/c]
     * @return boolean/string
     */
    static public function getToken($m) {
        $token = self::getStr('token', $m);
        if (false == $token) {
            $url = "https://api.weixin.qq.com/cgi-bin/token";
            $wx = self::$wx_app[$m];
            $param = array(
                'appid' => $wx['appid'],
                'secret' => $wx['appsecret'],
                'grant_type' => 'client_credential'
            );
            $data = Core_Plugin_Http::request($url, $param);
            $token = ($data && isset($data['access_token']) && $data['access_token']) ? $data['access_token'] : false;
            $token_ = $token ? (time() . ':' . $token) : '';
            Jf::cache()->set(self::TOKEN_KEY . $m, $token_, 7000);
        }
        return $token;
    }

    /**
     * 获取JS签名的票据信息
     * 
     * @param string $m 模块名称 [b/c]
     * @return boolean/string
     */
    static public function ticket($m) {
        $ticket = self::getStr('jssign', $m);
        if (false === $ticket) {
            $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket";
            $res = Core_Plugin_Http::request($url, array(
                'type' => 'jsapi',
                'access_token' => self::getToken($m)
            ));
            $ticket = isset($res['ticket']) ? $res['ticket'] : false;
            $ticket_ = $ticket ? (time() . ':' . $ticket) : '';
            Jf::cache()->set(self::JSSIGN_KEY . $m, $ticket_, 7000);
        }
        return $ticket;
    }

    /**
     * 获取OPENID
     * 
     * @param string $m 模块名称 [b/c]
     * @param string $goto 跳转链接
     * @param string $code 首次跳转获取的CODE字符串
     * @return boolean/string
     */
    static public function getOpenId($m, $goto, $code) {
        $data = array(
            'isJump' => true,
            'openid' => false,
            'url' => ''
        );
        $wx = self::$wx_app[$m];
        if ($code) {
            $url = "https://api.weixin.qq.com/sns/oauth2/access_token";
            $param = array(
                'appid' => $wx['appid'],
                'secret' => $wx['appsecret'],
                'code' => $code,
                'grant_type' => 'authorization_code'
            );
            $tmp = Core_Plugin_Http::request($url, $param);
            $data['openid'] = $tmp && isset($tmp['openid']) && $tmp['openid'] ? $tmp['openid'] : false;
        } elseif ($goto && is_string($goto)) {
            $data['url'] = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" . $wx['appid'] . "&redirect_uri={$goto}&response_type=code&scope=snsapi_base#wechat_redirect";
        }
        return $data;
    }

    /**
     * 获取用户信息OAuth2方式
     * 
     * @param string $m 模块名称 [b/c]
     * @param string $goto 跳转链接
     * @param string $code首次跳转获取的CODE字符串
     * @return array
     */
    static public function get_userinfoByOAuth2($m, $goto, $code) {
        $data = array(
            'isJump' => true,
            'info' => '',
            'url' => ""
        );
        $wx = self::$wx_app[$m];
        if ($code) {
            $url = "https://api.weixin.qq.com/sns/oauth2/access_token";
            $param = array(
                'appid' => $wx['appid'],
                'secret' => $wx['appsecret'],
                'code' => $code,
                'grant_type' => 'authorization_code'
            );
            $tmp = Core_Plugin_Http::request($url, $param);
            $openid = $tmp['openid'];
            $token = $tmp['access_token'];
            $url = "https://api.weixin.qq.com/sns/userinfo?access_token={$token}&openid={$openid}&lang=zh_CN";
            $res = Core_Plugin_Http::request($url);
            $data['info'] = ($res && isset($res['errcode']) && (intval($res['errcode']) > 0)) ? false : array(
                'openid' => $res['openid'],
                'nick' => Core_Plugin_Tool::checkStr($res['nickname']),
                'sex' => $res['sex'],
                'country' => $res['country'],
                'province' => $res['province'],
                'city' => $res['city'],
                'headimg' => $res['headimgurl'],
                'is_sub' => 0,
                'subtime' => '0000-00-00 00:00:00'
            );
        } elseif ($goto && $wx['appid']) {
            $data['url'] = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" . $wx['appid'] . "&redirect_uri={$goto}&response_type=code&scope=snsapi_userinfo#wechat_redirect";
        }
        return $data;
    }

    /**
     * 获取用户信息UnionID方式
     * 
     * @param string $openid 用户的OPENID
     * @param string $m 模块名称 [b/c]
     * @return array
     */
    static public function get_userinfoByUnionID($openid, $m) {
        $token = self::getToken($m);
        $url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token={$token}&openid={$openid}&lang=zh_CN";
        $res = Core_Plugin_Http::request($url);
        return ($res && isset($res['subscribe']) && (intval($res['subscribe']) == 0)) ? false : array(
            'openid' => $res['openid'],
            'nick' => Core_Plugin_Tool::checkStr($res['nickname']),
            'sex' => $res['sex'],
            'country' => $res['country'],
            'province' => $res['province'],
            'city' => $res['city'],
            'headimg' => $res['headimgurl'],
            'is_sub' => $res['subscribe'],
            'subtime' => date('Y-m-d H:i:s', $res['subscribe_time'])
        );
    }

    /**
     * 生成微信JS签名数据
     * 
     * @param string $m 模块名称 [b/c]
     * @return array
     */
    static public function getSign($m) {
        $ticket = self::ticket($m);
        if (false == $ticket) {
            return array();
        }
        $timestamp = time();
        $nonceStr = Core_Plugin_Tool::nonceStr();
        $url = HOST . $_SERVER['REQUEST_URI'];
        $string = "jsapi_ticket=$ticket&noncestr=$nonceStr&timestamp=$timestamp&url=$url";
        $signature = sha1($string);
        return array(
            "appId" => self::$wx_app[$m]['appid'],
            "nonceStr" => $nonceStr,
            "timestamp" => $timestamp,
            "url" => $url,
            "signature" => $signature,
            "rawString" => $string
        );
    }

    /**
     * 生成带参数的二维码链接
     * 
     * @param string $params 参数[默认为商铺编号]
     * @return string/boolean
     */
    static public function createQR($params) {
        $token = self::getToken('c');
        $url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token={$token}";
        $tmp = array(
            'action_name' => 'QR_LIMIT_STR_SCENE',
            'action_info' => array(
                'scene' => array(
                    'scene_str' => $params
                )
            )
        );
        // 获取二维码信息，并更新店铺二维码信息
        $data = Core_Plugin_Http::request($url, $tmp, 'JSON');
        return $data && isset($data['url']) ? $data['url'] : false;
    }
}
